package service

import (
	"XiangMu/define"
	"XiangMu/models"
	"XiangMu/utils"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"github.com/tealeg/xlsx/v3"
	"github.com/xuri/excelize/v2"

	"golang.org/x/exp/slices"
	"gorm.io/gorm"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

var REDIS_LOGIN_PREFIX = "login:"

func AdminLogin(c *gin.Context) {
	account := c.PostForm("account")
	password := c.PostForm("password")
	auth, _ := strconv.Atoi(c.Param("sign"))
	var name string
	if account == "" || password == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"msg":  "用户名和密码不能为空",
		})
		return
	}
	var branch models.Branch
	var committee models.Committee
	emptyB := models.Branch{}
	emptyC := models.Committee{}
	//支部登录
	if auth == 0 {
		models.DB.Model(models.Branch{}).Where("account = ? AND password = ? ", account, password).Find(&branch)
		if branch == emptyB {
			c.JSON(http.StatusBadRequest, gin.H{
				"code": -1,
				"msg":  "用户名密码错误",
			})
			return
		}
		name = branch.Name
	}
	//党员登录
	if auth == 1 {
		models.DB.Model(models.Committee{}).Where("account = ? AND password = ?", account, password).Find(&committee)
		if committee == emptyC {
			c.JSON(http.StatusBadRequest, gin.H{
				"code": -1,
				"msg":  "用户名密码错误",
			})
			return
		}
		name = committee.Name
	}

	//if err := models.DB.Where("account = ? AND password = ?", account, password).First(&admin).Error; err != nil {
	//	if err == gorm.ErrRecordNotFound {
	//		c.JSON(http.StatusUnauthorized, gin.H{
	//			"code": -1,
	//			"msg":  "用户名密码错误",
	//		})
	//		return
	//	}
	//	c.JSON(http.StatusInternalServerError, gin.H{
	//		"code": -1,
	//		"msg":  "内部错误: " + err.Error(),
	//	})
	//	return
	//}
	var token string
	var err error
	if branch != emptyB {
		token, err = utils.GenerateToken(branch.Id, branch.Account, 1)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": -1,
				"msg":  "生成 token 失败: " + err.Error(),
			})
			return
		}
	}
	if committee != emptyC {
		token, err = utils.GenerateToken(committee.Id, committee.Account, 2)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": -1,
				"msg":  "生成 token 失败: " + err.Error(),
			})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"name": name,
		"code": 200,
		"msg":  token,
	})
}

type admin struct {
	Password string `gorm:"column:password" json:"password"`
	Name     string `gorm:"column:name" json:"name"`
}

func UpdateSelf(c *gin.Context) {
	value, _ := c.Get("Auth")
	val, _ := c.Get("Auth")
	auth := value.(int)
	id := val.(int)
	var req admin
	var branch models.Branch
	var committee models.Committee
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求体"})
		return
	}
	if auth == 1 {
		err := models.DB.Model(models.Branch{}).Where("id = ?", id).Updates(&req).Error
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "数据库错误",
			})
			return
		}
		err = models.DB.Model(models.Branch{}).Where("id = ?", id).First(&branch).Error
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "数据库错误",
			})
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  branch,
		})
	}
	if auth == 2 {
		err := models.DB.Model(models.Committee{}).Where("id = ?", id).Updates(&req).Error
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "数据库错误",
			})
			return
		}
		err = models.DB.Model(models.Committee{}).Where("id = ?", id).First(&committee).Error
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500,
				"msg":  "数据库错误",
			})
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  committee,
		})
	}
}
func GetBirthdayFromID(id string) (time.Time, error) {
	if len(id) != 18 {
		return time.Time{}, fmt.Errorf("身份证号码长度不正确")
	}

	// 提取出生日部分（第7到14位）
	birthdayStr := id[6:14]
	// 解析为时间格式
	birthday, err := time.Parse("20060102", birthdayStr)
	if err != nil {
		return time.Time{}, fmt.Errorf("解析生日失败: %v", err)
	}

	return birthday, nil
}

// AddUser 添加用户
func AddUser(c *gin.Context) {
	name := c.PostForm("name")
	account := c.PostForm("account")
	password := c.PostForm("password")
	organization := c.PostForm("organization")
	sex := c.PostForm("sex")
	phone := c.PostForm("phone")
	identity := c.PostForm("identity_id")
	if account == "" || password == "" || organization == "" {
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  "账户，密码，所属支部必填",
		})
		return
	}
	var count int64
	models.DB.Model(models.User{}).Where("account = ?", account).Count(&count)
	if count > 0 {
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  "用户已存在",
		})
		return
	}
	//从身份证中获取生日
	birthday, err := GetBirthdayFromID(identity)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "身份证格式错误",
		})
		return
	}
	type user struct {
		Account      string     `gorm:"column:account" json:"account"`
		Name         string     `gorm:"column:name" json:"name"`
		Password     string     `gorm:"column:password" json:"password"`
		Sex          uint       `gorm:"sex" json:"sex"`
		IdentityId   string     `gorm:"column:identity_id" json:"identity_id"`
		Phone        string     `gorm:"column:phone;type:varchar(11)" json:"phone"`
		Organization uint       `gorm:"column:organization" json:"organization"`
		Birthday     *time.Time `gorm:"column:birthday" json:"birthday"`
	}
	newUser := user{
		Name:         name,
		Account:      account,
		Password:     password,
		Sex:          models.InvertedGenderMap[sex],
		Phone:        phone,
		IdentityId:   identity,
		Organization: models.InvertedOrganizationMap[organization],
		Birthday:     &birthday,
	}
	if err := models.DB.Create(&newUser).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "新建用户失败",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  newUser,
	})
}

type Students struct {
	Id           int    `json:"id"`
	Name         string `gorm:"column:name" json:"name"`
	Organization string `gorm:"column:organization" json:"organization"`
	Sex          string `gorm:"sex" json:"sex"`
	Nation       string `gorm:"column:nation" json:"nation"`
	Origin       string `gorm:"column:origin" json:"origin"`
	Birthday     string `gorm:"column:birthday" json:"birthday"`
	IdentityId   string `gorm:"column:identity_id" json:"identity_id"`
	Education    string `gorm:"column:education" json:"education"`
	Position     string `gorm:"column:position" json:"position"`
	IsDot        bool   `gorm:"column:is_dot" json:"is_dot"`
}

func GetStuUsers(c *gin.Context) {
	var users []models.User
	var students []Students
	Db := models.DB
	if name, isExist := c.GetQuery("name"); isExist && name != "" {
		Db = Db.Where("name LIKE ?", "%"+name+"%")
	}
	if identityId, isExist := c.GetQuery("identity_id"); isExist && identityId != "" {
		Db = Db.Where("identity_id LIKE ?", "%"+identityId+"%")
	}
	if err := Db.Find(&users).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "获取数据失败",
		})
		return

	}
	responses := models.UsersToUserResponses(users)
	err := copier.Copy(&students, &responses)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "获取数据失败",
		})
		return
	}
	ids, err := SelectDot()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "数据获取失败",
		})
		return
	}

	for i := 0; i < len(users); i++ {
		if slices.Contains(ids, students[i].Id) {
			students[i].IsDot = true
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  students,
	})
}
func SelectDot() ([]int, error) {
	var ids []int
	err := models.DB.Model(&models.Step{}).Distinct("user_id").Where("status=?", 1).Find(&ids).Error
	if err != nil {
		return nil, err
	}
	return ids, nil
}

type AllUsers struct {
	Id           int    `json:"id"`
	Account      string `gorm:"column:account" json:"account"`
	Password     string `gorm:"column:password" json:"password"`
	Name         string `gorm:"column:name" json:"name"`
	Sex          string `gorm:"sex" json:"sex"`
	Phone        string `gorm:"column:phone;type:varchar(11)" json:"phone"`
	IdentityId   string `gorm:"column:identity_id" json:"identity_id"`
	Organization string `gorm:"column:organization" json:"organization"`
}

// 人员管理
func GetAllUsers(c *gin.Context) {
	var users []models.User
	var allUsers []AllUsers
	Db := models.DB
	if name, isExist := c.GetQuery("name"); isExist && name != "" {
		Db = Db.Where("name LIKE ?", "%"+name+"%")
	}
	if account, isExist := c.GetQuery("account"); isExist && account != "" {
		Db = Db.Where("account LIKE ?", "%"+account+"%")
	}
	if organization, isExist := c.GetQuery("organization"); isExist && organization != "" {
		Db = Db.Where("organization = ?", models.InvertedOrganizationMap[organization])
	}
	if err := Db.Find(&users).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "查询失败",
		})
		return
	}
	responses := models.UsersToUserResponses(users)
	copier.Copy(&allUsers, responses)
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data": allUsers,
	})
}

// DeleteById 根据ID删除用户
func DeleteById(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var user models.User
	//TODO：id不存在时应该返回用户不存在
	if err := models.DB.First(&user, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(http.StatusNotFound, gin.H{
				"code": -1,
				"msg":  "用户不存在",
			})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "查询用户失败",
		})
		return
	}

	// 在事务中执行删除操作
	if err := models.DB.Transaction(func(tx *gorm.DB) error {
		// 删除用户对应的步骤
		if err := tx.Where("user_id = ?", id).Delete(&models.Step{}).Error; err != nil {
			return err
		}
		// 删除用户
		if err := tx.Where("id = ?", id).Delete(&user).Error; err != nil {
			return err
		}
		return nil
	}); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "删除失败: " + err.Error(),
		})
		return
	}
	// 更新缓存
	cacheKey := fmt.Sprintf("user:%d", id)
	models.RDB.Del(c, cacheKey)

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "删除成功",
	})
}

// DeleteByIds 批量删除用户
func DeleteByIds(c *gin.Context) {
	var req struct {
		IDs []uint `json:"ids"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求体"})
		return
	}

	// 检查是否有用户存在
	var count int64
	if err := models.DB.Model(&models.User{}).Where("id IN ?", req.IDs).Count(&count).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "检查用户存在失败"})
		return
	}
	if count == 0 {
		c.JSON(http.StatusNotFound, gin.H{"error": "未找到指定用户"})
		return
	}

	if int(count) != len(req.IDs) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "部分用户ID不存在"})
		return
	}

	tx := models.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 先删除步骤记录，避免外键约束问题（如果有关联关系）
	if err := tx.Where("user_id IN ?", req.IDs).Delete(&models.Step{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除用户步骤失败: " + err.Error()})
		return
	}

	// 再删除用户
	if err := tx.Where("id IN ?", req.IDs).Delete(&models.User{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除用户失败: " + err.Error()})
		return
	}

	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "事务提交失败: " + err.Error()})
		return
	}
	for i := 0; i < len(req.IDs); i++ {
		// 更新缓存
		cacheKey := fmt.Sprintf("user:%d", req.IDs[i])
		models.RDB.Del(c, cacheKey)

	}
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "删除成功",
	})
}

// UpdateById 根据ID更新用户信息
func UpdateById(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Param("id"))
	name, _ := c.GetQuery("name")
	account, _ := c.GetQuery("account")
	password, _ := c.GetQuery("password")
	organization, _ := c.GetQuery("organization")
	sex, _ := c.GetQuery("sex")
	phone, _ := c.GetQuery("phone")
	identity, _ := c.GetQuery("identity")
	if account == "" || password == "" || organization == "" {
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  "账户，密码，所属支部不能为空",
		})
		return
	}
	tx := models.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "事务回滚"})
		}
	}()
	//如果党支部改动存入redis
	redisOrgKey := "OrderOrganization:" + string(rune(userId))
	var org uint
	//models.DB.Model(&models.User{}).Select("organization").Where("id=?", userId).First(&org)
	err := models.RDB.Set(context.Background(), redisOrgKey, models.OrganizationMap[org], 0).Err()
	if err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "redid错误",
		})
	}
	var stepId int
	err = tx.Model(&models.User{}).Select("step").Where("id=?", userId).First(&stepId).Error
	if err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "数据库错误"})
		return
	}
	cacheKeyStep := fmt.Sprintf("OrgStep:%d", userId)
	err = models.RDB.Set(c, cacheKeyStep, stepId, 0).Err()
	if err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "redis错误"})
		return
	}
	//TODO:支部应该改动学生的全部信息
	type updateUserResp struct {
		Account      string `json:"account"`
		Password     string `json:"password"`
		Name         string `json:"name"`
		Phone        string `json:"phone"`
		Sex          string `json:"sex"`
		IdentityId   string `json:"identity"`
		Organization string `gorm:"column:organization" json:"organization"`
	}
	type updateUserMysql struct {
		Account      string `json:"account"`
		Password     string `json:"password"`
		Name         string `json:"name"`
		Phone        string `json:"phone"`
		Sex          uint   `json:"sex"`
		IdentityId   string `json:"identity"`
		Organization uint   `gorm:"column:organization" json:"organization"`
	}
	user := updateUserMysql{
		Account:      account,
		Password:     password,
		Name:         name,
		Phone:        phone,
		Sex:          models.InvertedGenderMap[sex],
		IdentityId:   identity,
		Organization: models.InvertedOrganizationMap[organization],
	}
	result := tx.Model(&models.User{}).Where("id = ?", userId).Updates(user).Update("organization", models.InvertedOrganizationMap[organization])
	if result.Error != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
		return
	}

	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "事务提交失败"})
		return
	}
	// 更新缓存
	cacheKey := fmt.Sprintf("user:%d", userId)
	models.RDB.Del(c, cacheKey)
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg": updateUserResp{
			Account:      user.Account,
			Password:     user.Password,
			Name:         user.Name,
			Phone:        user.Phone,
			IdentityId:   identity,
			Organization: organization,
			Sex:          sex,
		},
	})
}

// createExcelFile 创建Excel文件
func createExcelFile(users []models.User) (*excelize.File, error) {
	f := excelize.NewFile()
	headers := []string{"Name", "XueHao", "Sex", "Nation", "Birthday", "Origin", "Phone", "Address"}
	for col, header := range headers {
		cell := fmt.Sprintf("%c1", 'A'+col)
		if err := f.SetCellValue("Sheet1", cell, header); err != nil {
			return nil, err
		}
	}

	for row, user := range users {
		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", row+2), user.Birthday)
		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", row+2), user.Name)
		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", row+2), user.XueHao)
		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", row+2), models.GenderMap[user.Sex])
		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", row+2), user.Nation)

		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", row+2), user.Origin)
		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", row+2), user.Phone)
		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", row+2), user.Address)
	}

	return f, nil
}

// ExportUsersToExcel 导出用户数据到Excel
func ExportUsersToExcel(c *gin.Context) {
	var users []models.User
	Db := models.DB
	if name, isExist := c.GetQuery("name"); isExist && name != "" {
		Db = Db.Where("name LIKE ?", "%"+name+"%")
	}
	if number, isExist := c.GetQuery("xueHao"); isExist && number != "" {
		Db = Db.Where("xue_hao = ?", number)
	}
	if status, isExist := c.GetQuery("status"); isExist && status != "" {
		Db = Db.Where("status = ?", status)
	}
	if org, isExist := c.GetQuery("organization"); isExist && org != "" {
		Db = Db.Where("organization = ?", org)
	}
	if err := Db.Find(&users).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	//将excecl上传到阿里云服务器
	tempFile := filepath.Join("tmp", "users.xlsx")
	file, err := createExcelFile(users)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建Excel文件失败" + err.Error()})
		return
	}
	if err := file.SaveAs(tempFile); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存Excel文件失败" + err.Error()})
		return
	}
	excelURL := "https://web-aliyuncjh.oss-cn-guangzhou.aliyuncs.com/excel/" + "users.xlsx"
	// 检查文件是否存在
	if _, err := os.Stat(tempFile); os.IsNotExist(err) {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "文件未生成"})
		return
	}
	utils.ALiYunOssPutExcel(tempFile)
	// 返回文件
	c.JSON(http.StatusOK, gin.H{
		"url": excelURL,
	})

	// 确保文件成功返回后再删除
	defer func() {
		if err := os.Remove(tempFile); err != nil {
			log.Printf("删除临时文件失败: %v", err)
		}
	}()
	//file, err := createExcelFile(users)
	//if err != nil {
	//	c.JSON(http.StatusInternalServerError, gin.H{"error": "创建Excel文件失败"})
	//	return
	//}
	//tempFile := "users.xlsx"
	//if err := file.SaveAs(tempFile); err != nil {
	//	c.JSON(http.StatusInternalServerError, gin.H{"error": "保存Excel文件失败"})
	//	return
	//}
	//c.File(tempFile)
	//defer os.Remove(tempFile)
}

type UserInfo struct {
	Account      string     `gorm:"column:account" json:"account"`
	Password     string     `gorm:"column:password" json:"password"`
	Name         string     `gorm:"column:name" json:"name"`
	Sex          uint       `gorm:"sex" json:"sex"`
	Phone        string     `gorm:"column:phone" json:"phone"`
	IdentityId   string     `gorm:"column:identity_id" json:"identity_id"`
	Organization uint       `gorm:"column:organization" json:"organization"`
	Birthday     *time.Time `gorm:"column:birthday" json:"birthday"`
}

func AddUserByExcel(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	// 打开上传的文件
	f, err := file.Open()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer f.Close()

	// 解析Excel文件
	xlFile, err := xlsx.OpenReaderAt(f, file.Size)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	var users []UserInfo
	sheet := xlFile.Sheets[0]
	for i := 1; i < sheet.MaxRow; i++ { // 从第二行开始读取数据
		row, err := sheet.Row(i)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		acc := row.GetCell(0).String()
		if acc == "" {
			continue
		}
		iden, err := convertScientificToFullNumber(row.GetCell(5).String())
		bir, _ := GetBirthdayFromID(iden)
		user := UserInfo{
			Account:      acc,
			Password:     row.GetCell(1).String(),
			Name:         row.GetCell(2).String(),
			Sex:          models.InvertedGenderMap[row.GetCell(3).String()],
			Phone:        row.GetCell(4).String(),
			IdentityId:   iden,
			Organization: models.InvertedOrganizationMap[row.GetCell(6).String()],
			Birthday:     &bir,
		}
		users = append(users, user)
	}
	// 这里可以将users保存到数据库
	tx := models.DB.Begin()
	if tx.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": tx.Error.Error()})
		return
	}
	// 批量插入用户数据
	for _, user := range users {
		if err := tx.Create(&user).Error; err != nil {
			tx.Rollback() // 回滚事务
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	// 提交事务
	if err := tx.Commit().Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "文件上传成功", "users": users})
}

// 将科学计数法转化为数字字符串
func convertScientificToFullNumber(scientific string) (string, error) {
	// 如果已经是完整数字，直接返回
	if !strings.ContainsAny(scientific, "eE") {
		return scientific, nil
	}
	// 将科学计数法转换为浮点数
	floatVal, err := strconv.ParseFloat(scientific, 64)
	if err != nil {
		return "", err
	}
	// 将浮点数转换为字符串（去掉小数点）
	fullNumber := fmt.Sprintf("%.0f", floatVal)
	return fullNumber, nil
}

//type ReviewRequest struct {
//	UserId int  `json:"user_id"`
//	StepId int  `json:"step_id"`
//	Action uint `json:"action"`
//}

func AdminGetStepInfo(c *gin.Context) {
	//value, _ := c.Get("Auth")
	//auth := value.(int)
	//var sta string
	stepId := c.Param("sid")
	//先查redis
	userId, _ := strconv.Atoi(c.Param("uid"))
	//userId, _ := utils.ToInt(value)
	data, err := StepInfo(stepId, userId)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	handleData := HandleData(data, stepId)
	if stepId == "17" {
		split := strings.Split(data["预备期起止时间"], "至")
		temp := handleData["17-5"]
		// 2. 修改字段
		temp.Content = split
		// 3. 存回 map
		handleData["17-5"] = temp
	}
	if stepId == "7" {
		split := strings.Split(data["公示起止时间"], "至")
		temp := handleData["7-2"]
		// 2. 修改字段
		temp.Content = split
		// 3. 存回 map
		handleData["7-2"] = temp
	}
	if stepId == "22" {
		split := strings.Split(data["转正公示起止时间"], "至")
		temp := handleData["22-2"]
		// 2. 修改字段
		temp.Content = split
		// 3. 存回 map
		handleData["22-2"] = temp
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  handleData,
	})
}
func GetBranchById(c *gin.Context) {
	userId := c.Param("bid")
	var branch models.Branch
	err := models.DB.Model(&models.Branch{}).Where("id = ?", userId).First(&branch).Error
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  branch,
	})
}

func GetBranches(c *gin.Context) {
	var branches []models.Branch
	Db := models.DB
	if name, isExist := c.GetQuery("name"); isExist && name != "" {
		Db = Db.Where("name LIKE ?", "%"+name+"%")
	}
	if account, isExist := c.GetQuery("account"); isExist && account != "" {
		Db = Db.Where("account = ?", account)
	}
	if err := Db.Find(&branches).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data": branches,
	})
}

func GetUserStatus(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Param("uid"))
	//redisKEY
	cacheKeyUser := fmt.Sprintf("user:%d", userId)
	var userStatus models.UserStatus
	//先查redis
	userInfo, err := models.RDB.Get(c, cacheKeyUser).Result()
	//有数据直接返回
	if err == nil {
		if err = json.Unmarshal([]byte(userInfo), &userStatus); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		res := utils.ConvertUserToLabelValue(userStatus)
		c.JSON(http.StatusOK, gin.H{
			"userInfo": res,
			"stepInfo": HandleStatus(userId),
		})
		return
	}
	//木有数据就查询数据库
	err = models.DB.Model(&models.User{}).Where("id = ?", userId).First(&userStatus).Error
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	//写入redis
	bytes, _ := json.Marshal(userStatus)
	if err := models.RDB.Set(c, cacheKeyUser, bytes, 24*time.Hour).Err(); err != nil {
		log.Printf("缓存写入失败: %v", err)
	}
	res := utils.ConvertUserToLabelValue(userStatus)
	c.JSON(http.StatusOK, gin.H{
		"userInfo": res,
		"stepInfo": HandleStatus(userId),
	})
	return
}

func HandleStatus(uid int) []models.Data {
	var res []models.Data
	res = append(res, deepCopyStatus(define.Status1))
	res = append(res, deepCopyStatus(define.Status2))
	res = append(res, deepCopyStatus(define.Status3))
	res = append(res, deepCopyStatus(define.Status4))
	res = append(res, deepCopyStatus(define.Status5))
	var user models.User
	models.DB.Model(models.User{}).Where("id = ?", uid).First(&user)
	step := int(user.Step)
	//var stepStatus uint
	//models.DB.Model(models.Step{}).Where("user_id = ? AND step_id", uid, step).First(&stepStatus)
	for i := 1; i < step; i++ {
		res[define.StepToStatus(i)].StateCartData[define.StepToIndex[i]].BottomText = "Completed"
	}
	if step < 25 {
		res[define.StepToStatus(step)].StateCartData[define.StepToIndex[step]].BottomText = "InProgress"
	}
	return res
}

func deepCopyStatus(status models.Data) models.Data {
	steps := []models.Steps{}
	for i := 0; i < len(status.StateCartData); i++ {
		steps = append(steps, define.DeepCopyStep(status.StateCartData[i]))
	}
	return models.Data{
		Title:         status.Title,
		StateCartData: steps,
	}
}
func AddBranch(c *gin.Context) {
	name, _ := c.GetQuery("name")
	account, _ := c.GetQuery("account")
	password, _ := c.GetQuery("password")

	if account == "" || password == "" || name == "" {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "账户，密码，名称必填",
		})
		return
	}
	var cou int64
	models.DB.Model(models.Branch{}).Where("account=?", account).Count(&cou)
	if cou > 0 {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "账号重复",
		})
		return
	}
	branch := models.Branch{
		Account:  account,
		Name:     name,
		Password: password,
	}
	err := models.DB.Create(&branch).Error
	if err != nil {
		c.JSON(500, gin.H{
			"code": 500,
			"msg":  "创建支部账号失败",
		})
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  branch,
	})
}
func DelBByIds(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	// 检查是否有用户存在
	var count int64
	if err := models.DB.Model(&models.Branch{}).Where("id = ?", id).Count(&count).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "检查用户存在失败"})
		return
	}
	if count == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": "未找到指定用户"})
		return
	}

	tx := models.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 删除用户
	if err := tx.Where("id = ?", id).Delete(&models.Branch{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"code": 400, "error": "删除用户失败: " + err.Error()})
		return
	}
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "事务提交失败: " + err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "删除成功",
	})
}
func StartNextStep(c *gin.Context) {
	uId := c.Param("uid")
	sId := c.Param("sid")
	if uId == "" || sId == "" {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "参数缺失",
		})
		return
	}
	userId, _ := strconv.Atoi(uId)
	stepId, _ := strconv.Atoi(sId)
	if stepId < 0 || stepId > 24 {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	var nowStepId int
	err := models.DB.Model(models.User{}).Select("step").Where("id=?", userId).Scan(&nowStepId).Error
	if err != nil {
		c.JSON(500, gin.H{
			"code": 500,
			"msg":  "数据库错误",
		})
		return
	}
	if nowStepId > stepId {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "该步骤已开始",
		})
		return
	}
	if nowStepId < stepId {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "前面的步骤未完成",
		})
		return
	}
	newStepId := stepId + 1
	if err = models.DB.Transaction(func(tx *gorm.DB) error {
		err = tx.Exec("UPDATE users SET step = ? WHERE id = ? ", newStepId, userId).Error
		if err != nil {
			return err
		}
		err = tx.Exec("UPDATE steps SET status = ? WHERE user_id = ? AND step_id = ?", 2, userId, stepId).Error
		if err != nil {
			return err
		}
		if newStepId != 25 {
			err = tx.Exec("UPDATE steps SET status = ? WHERE user_id = ? AND step_id = ?", 1, userId, newStepId).Error
			if err != nil {
				return err
			}
		}
		return nil
	}); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "更新失败: " + err.Error(),
		})
		return
	}

	c.JSON(200, gin.H{
		"code": 200,
		"msg":  "成功",
	})
}

// UserWordFill 处理用户信息填充
func GetUserWordFill(c *gin.Context) {
	var req struct {
		IDs []uint `json:"ids"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求体"})
		return
	}
	id, _ := strconv.Atoi(c.Param("uid"))
	//n, _ := strconv.Atoi(c.Param("num"))
	var user models.User
	if err := models.DB.Where("id = ?", id).First(&user).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  err.Error(),
		})
		return
	}
	var url string
	var url1 string
	var url2 string
	var pdf string
	var pdf1 string
	var pdf2 string
	uResp := models.UserToUserResponse(user)
	for i := 0; i < len(req.IDs); i++ {
		n := req.IDs[i]
		if n == 0 {
			pdf, url = utils.WordFill(uResp)
			defer utils.DelFile(pdf)
		}
		if n == 1 {
			pdf1, url1 = utils.WordFill1(uResp)
			defer utils.DelFile(pdf1)
		}
		if n == 2 {
			pdf2, url2 = utils.WordFill2(uResp)
			defer utils.DelFile(pdf2)
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"url":  url,
		"url1": url1,
		"url2": url2,
	})
}

func UpdateCTS(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("uid"))
	var status int
	models.DB.Model(models.Step{}).Select("status").Where("user_id = ? AND step_id=?", id, 5).Find(&status)
	if status != 2 {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": "初始联系人尚未提交"})
		return
	}
	var req map[string]string
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": "无效的请求体"})
		return
	}

	// 将 Data 转换为 JSON 字符串
	dataJSON, err := json.Marshal(req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "数据序列化失败"})
		return
	}

	//存储修改后的联系人信息
	cacheKey := fmt.Sprintf("Contacts:%d", id)
	var stepId int
	models.DB.Model(&models.User{}).Select("step").Where("id=?", id).First(&stepId)
	cacheKeyStep := fmt.Sprintf("ContactsStep:%d", id)
	err = models.RDB.Set(c, cacheKeyStep, stepId, 0).Err()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "redis错误"})
		return
	}
	err = models.RDB.Set(c, cacheKey, dataJSON, 0).Err()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "redis错误"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "培养联系人更新成功",
	})
}

// 更换介绍人
func UpdateSP(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("uid"))
	var status int
	models.DB.Model(models.Step{}).Select("status").Where("user_id = ? AND step_id=?", id, 9).Find(&status)
	if status != 2 {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": "初始介绍人尚未提交"})
		return
	}
	var req map[string]string
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": "无效的请求体"})
		return
	}
	// 将 Data 转换为 JSON 字符串
	dataJSON, err := json.Marshal(req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "数据序列化失败"})
		return
	}
	cacheKey := fmt.Sprintf("Sponsor:%d", id)
	err = models.RDB.Set(c, cacheKey, dataJSON, 0).Err()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "redis错误"})
		return
	}
	var stepId int
	models.DB.Model(&models.User{}).Select("step").Where("id=?", id).First(&stepId)
	cacheKeyStep := fmt.Sprintf("SponsorStep:%d", id)
	err = models.RDB.Set(c, cacheKeyStep, stepId, 0).Err()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "redis错误"})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "入党介绍人更新成功",
	})
}
